import { upperFirst } from "lodash";
/**
 * super注解
 * 因为通过extends继承无法通过super调用父类方法
 * 这里可以通过注解将当前方法复制为一个 super加当前方法名首字母大写 的方法
 * 子类可以通过super加当前方法名首字母大写来调用父类的方法
 * 暂未验证多重继承引入是否有效
 *
 * @export
 * @return {*}  {*}
 */
export function superFun(): any {
    return function(target: any, key: any, descriptor: any) {
        target[`super${upperFirst(key)}`] = target[key];
        return descriptor;
    };
}
/**
 * 防抖注解
 * 在指定时间段内函数只执行最后一次
 * @export
 * @param {number} timeout 防抖时间（毫秒）
 * @return {*}
 */
export function debounce(timeout: number):any {
    const instanceMap = new Map(); // 创建一个Map的数据结构，将实例化对象作为key
    return function(target: any, key: any, descriptor: any) {
        return Object.assign({}, descriptor, {
            value: function value() {
                // 清除延时器
                clearTimeout(instanceMap.get(this));
                // 设置延时器
                instanceMap.set(this, setTimeout(() => {
                    // 调用该方法
                    // eslint-disable-next-line prefer-rest-params
                    descriptor.value.apply(this, arguments);
                    // 将延时器设置为 null
                    instanceMap.set(this, null);
                }, timeout));
            }
        })
    }
}

/**
 * 限流注解
 * 在指定时间段内函数只执行第一次
 *
 * @export
 * @param {number} delay 限流时间（毫秒）
 * @return {*}
 */
export function limiting(delay: number): any {
    // 创建一个Map的数据结构，将实例化对象作为key
    const instanceMap = new Map();
    return function(target: any, key: any, descriptor: any) {
        return Object.assign({}, descriptor, {
            value: function value() {
                // 获取函数上次执行时间戳，没有则为0
                const lastTime = instanceMap.get(this) || 0,
                    // 获取当前时间戳
                    now = +new Date();
                // 如果当前时间减去函数上次执行时间大于限流时间
                // 就执行指定函数
                if (now - lastTime > delay) {
                    // 执行函数
                    // eslint-disable-next-line prefer-rest-params
                    descriptor.value.apply(this, arguments);
                    // 记录函数上次执行时间
                    instanceMap.set(this, +new Date());
                }
            }
        })
    }
}
export default {}